var GownFullBrowserDetect = Base.extend({
	constructor: null,
	BROWSER_UNKNOWN: 0,
	BROWSER_IE: 1,
	BROWSER_FIREFOX: 2,
	BROWSER_OPERA: 3,
	BROWSER_KONQUEROR: 4,
	BROWSER_SAFARI: 5,
	BROWSER_MINIMO: 6,
	ENGINE_UNKNOWN: 0,
	ENGINE_GECKO: 1,
	ENGINE_TRIDENT: 2,
	ENGINE_WEBKIT: 3,
	ENGINE_KHTML: 4,
	ENGINE_OPERA: 5,
	OS_UNKNOWN: 0,
	OS_WINDOWS: 1,
	OS_LINUX: 2,
	OS_MAC: 3,
	current_os: null,
	current_os_version: null,
	current_browser: null,
	current_engine: null,
	use_attachEvent: null,
	use_addEventListener: null,
	use_key_addEventListener: null,
	use_mouse_addEventListener: null,
	need_windowreference: null,
	need_iframe_jssrc: null,
	use_css_position_fixed: null,
	use_css_position_absolute: null,
	use_css_display_tablecell: null,
	use_css_display_inline: null,
	bad_keypress: null,
	backspace_keypress: null,
	running_mobile: null,
	
	unicode_level: null,

	DOM_MutationEvents20: null,

	init: function()
	{
		this.init_useragent();
		if(this.current_browser == this.BROWSER_UNKNOWN) this.init_objtest();
		//this.unicode_level = 1.1;
		this.domtest();

		Debug.trace(0,"GownFullBrowserDetect: Running Unicode Level %f",this.unicode_level);

		Debug.present && (this.current_os == this.OS_WINDOWS) && Debug.trace(0,'GownFullBrowserDetect: Running on Windows');
		Debug.present && (this.current_os == this.OS_LINUX) && Debug.trace(0,'GownFullBrowserDetect: Running on Linux');
		Debug.present && (this.current_os == this.OS_MAC) && Debug.trace(0,'GownFullBrowserDetect: Running on Mac');
		Debug.present && (this.current_os == this.OS_UNKNOWN) && Debug.trace(0,'GownFullBrowserDetect: Running on Unknown OS');

		Debug.present && Debug.trace(0,'GownFullBrowserDetect: OS version string "%s"',this.current_os_version);

		Debug.present && (this.current_browser == this.BROWSER_IE) && Debug.trace(0,"GownFullBrowserDetect: Running Internet Explorer.");
		Debug.present && (this.current_browser == this.BROWSER_FIREFOX) && Debug.trace(0,"GownFullBrowserDetect: Running Mozilla Firefox.");
		Debug.present && (this.current_browser == this.BROWSER_OPERA) && Debug.trace(0,"GownFullBrowserDetect: Running Opera.");
		Debug.present && (this.current_browser == this.BROWSER_KONQUEROR) && Debug.trace(0,"GownFullBrowserDetect: Running Konqueror.");
		Debug.present && (this.current_browser == this.BROWSER_SAFARI) && Debug.trace(0,"GownFullBrowserDetect: Running Safari.");
		Debug.present && (this.current_browser == this.BROWSER_MINIMO) && Debug.trace(0,"GownFullBrowserDetect: Running Minimo.");
		Debug.present && (this.current_browser == this.BROWSER_UNKNOWN) && Debug.trace(0,"GownFullBrowserDetect: Running unknown browser.");
		Debug.present && (this.running_mobile) && Debug.trace(0,"GownFullBrowserDetect: Running Mobile device.");
		Debug.present && this.use_attachEvent && Debug.trace(0,"GownFullBrowserDetect: GownFull can use attachEvent.");
		Debug.present && this.use_addEventListener && Debug.trace(0,"GownFullBrowserDetect: GownFull can use addEventListener.");
		Debug.present && this.use_key_addEventListener && Debug.trace(0,"GownFullBrowserDetect: GownFull should use addEventListener on key events.");
		Debug.present && this.use_mouse_addEventListener && Debug.trace(0,"GownFullBrowserDetect: GownFull should use addEventListener on mouse events.");
		Debug.present && this.use_css_position_fixed && Debug.trace(0,"GownFullBrowserDetect: GownFull can use position: fixed in CSS.");
		Debug.present && this.use_css_position_absolute && Debug.trace(0,"GownFullBrowserDetect: GownFull can use position: absolute in CSS.");
		Debug.present && this.use_css_display_tablecell && Debug.trace(0,"GownFullBrowserDetect: GownFull can use display: table-cell in CSS.");
		Debug.present && this.use_css_display_inline && Debug.trace(0,"GownFullBrowserDetect: GownFull can use display: inline in CSS.");

	},
	init_useragent: function()
	{
		Debug.trace(0,"GownFullBrowserDetect: Detecting using user-agent...");

		var Useragent = navigator.userAgent;

		Debug.trace(0,"GownFullBrowserDetect: %s",Useragent);

		var useragent = Useragent.toLowerCase();

		var isIE = (useragent.indexOf('msie') < 0) ? false : true;
		var isFirefox = (useragent.indexOf('firefox') < 0) ? false : true;
		var isOpera = (useragent.indexOf('opera') < 0) ? false : true;
		var isKonqueror = (useragent.indexOf('konqueror') < 0) ? false : true;
		var isSafari = (useragent.indexOf('safari') < 0) ? false : true;
		var isMinimo = (useragent.indexOf('minimo') < 0) ? false : true;
		var isWinCE = (useragent.indexOf('windows ce') < 0) ? false : true;

		if(isOpera && isIE) isIE = false;

		if(isIE) this.current_browser = this.BROWSER_IE;
		else if(isFirefox) this.current_browser = this.BROWSER_FIREFOX;
		else if(isOpera) this.current_browser = this.BROWSER_OPERA;
		else if(isKonqueror) this.current_browser = this.BROWSER_KONQUEROR;
		else if(isSafari) this.current_browser = this.BROWSER_SAFARI;
		else if(isMinimo) this.current_browser = this.BROWSER_MINIMO;
		else this.current_browser = this.BROWSER_UNKNOWN;

		if(isIE) this.current_engine = this.ENGINE_TRIDENT;
		else if(isFirefox || isMinimo) this.current_engine = this.ENGINE_GECKO;
		else if(isKonqueror) this.current_engine = this.ENGINE_KHTML;
		else if(isSafari) this.current_engine = this.ENGINE_WEBKIT;
		else if(isOpera) this.current_engine = this.ENGINE_OPERA;
		else this.current_engine = this.ENGINE_UNKNOWN;

		this.use_attachEvent = (isIE) ? true : false;
		this.use_addEventListener = (isFirefox || isMinimo || isOpera || isKonqueror || isSafari) ? true : false;
		this.use_key_addEventListener = (isFirefox || isMinimo || isKonqueror || isSafari) ? true : false;
		this.use_mouse_addEventListener = (isFirefox || isMinimo || isOpera || isKonqueror || isSafari) ? true : false;
		this.need_windowreference = (isKonqueror || isSafari) ? true : false;
		this.need_iframe_jssrc = (isIE) ? true : false;
		this.bad_keypress = (isIE) ? true : false;
		// keypress will be fired if backspace is pressed "continously"
		// some browsers will fire many keydown instead of keypress
		this.backspace_keypress = (isFirefox || isMinimo) ? true : false;
		this.running_mobile = (isWinCE) ? true : false;
		if(this.running_mobile) {
			this.use_css_position_fixed = false;
			this.use_css_position_absolute = false;
		}
		else {
			this.use_css_position_fixed = (isFirefox || isMinimo || isOpera || isKonqueror || isSafari) ? true : false;
			this.use_css_position_absolute = true;
		}
		this.use_css_display_tablecell = (!isIE) ? true : false;
		this.use_css_display_inline = true;

		if(useragent.indexOf('windows') >= 0) {
			this.current_os = this.OS_WINDOWS;
			// try to get version using regex...
			var regex = /Windows NT (\d)\.(\d)/
			var parts;

			parts = regex.exec(Useragent);
			if(parts) this.current_os_version = 'NT'+parts[1]+'.'+parts[2];
			else this.current_os_version = null;
		}
		else if(useragent.indexOf('linux') >= 0) {
			this.current_os = this.OS_LINUX;
		}
		else if(useragent.indexOf('mac os x') >= 0) { // Mac OS X
			this.current_os = this.OS_MAC;
			this.current_os_version = 'X';
		}
		else if(useragent.indexOf('macintosh') >= 0) {
			this.current_os = this.OS_MAC;
		}
		else this.current_os = this.OS_UNKNOWN;

		// assumed, we must have unicode 1.1...
		this.unicode_level = 1.1;
		// check OS...
		if(this.current_os == this.OS_LINUX) { // Unicode 3.1
			this.unicode_level = 3.1;
		}
		else if(this.current_os == this.OS_WINDOWS) {
			// check version...
			if(this.current_os_version) {
				if(this.current_os_version == 'NT6.0') { // Vista
					this.unicode_level = 3.1;
				}
				else if(this.current_os_version.substr(0,3) == 'NT5') { // XP, 2003
					this.unicode_level = 2.0;
				}
			}
		}
		else if(this.current_os == this.MAC) {
			if(this.current_os_version == 'X') this.unicode_level = 3.0;
		}
		else this.unicode_level = 1.1;
	},
	init_objtest: function()
	{
		Debug.trace(0,"GownFullBrowserDetect: Detecting using object existence...");
	
		this.use_attachEvent = (document.attachEvent) ? true : false;
		this.use_addEventListener = (document.addEventListener) ? true : false;
		this.use_key_addEventListener = (document.addEventListener) ? true : false;
		this.use_mouse_addEventListener = (document.addEventListener) ? true : false;
		this.use_css_position_fixed = true;
		this.need_iframe_jssrc = false;
		this.use_css_display_tablecell = (document.attachEvent) ? true : false;
		this.use_css_display_inline = true;
		this.bad_keypress = false;
		this.running_mobile = false;

		lib.RunScript('var x = 123;');
		try { this.need_windowreference = (!x || x != 123) ? true : false; }
		catch(e) { this.need_windowreference = true; }

		if(this.use_attachEvent) {
			this.current_browser = this.BROWSER_IE;
			this.current_engine = this.ENGINE_TRIDENT;
			this.current_os = this.OS_WINDOWS;
		}
		else {
			this.current_browser = this.BROWSER_UNKNOWN;
			this.current_engine = this.ENGINE_UNKNOWN;
			this.current_os = this.OS_UNKNOWN;
		}
		// assumed to have unicode 5.0...
		this.unicode_level = 5.0;
	},
	domtest: function()
	{
		if(document.implementation.hasFeature('MutationEvents','2.0') || window.MutationEvent) {
			this.DOM_MutationEvents20 = true;
			Debug.present && Debug.trace(0,'GownFullBrowserDetect: DOM Level 2 Events MutationEvents is supported in this browser.');

		}
		else {
			this.DOM_MutationEvents20 = false;
			Debug.present && Debug.trace(0,'GownFullBrowserDetect: DOM Level 2 Events MutationEvents is not supported in this browser.');
		}
	},
	isUnicodeVisible: function(code)
	{
/*
Code point range        Block name                              Release
U+3400 - U+4DB5         CJK Unified Ideographs Extension A      3.0
U+4E00 - U+9FA5         CJK Unified Ideographs                  1.1
U+9FA6 - U+9FBB         CJK Unified Ideographs                  4.1
U+F900 - U+FA2D         CJK Compatibility Ideographs            1.1
U+FA30 - U+FA6A         CJK Compatibility Ideographs            3.2
U+FA70 - U+FAD9         CJK Compatibility Ideographs            4.1
U+20000 - U+2A6D6       CJK Unified Ideographs Extension B      3.1
U+2F800 - U+2FA1D       CJK Compatibility Supplement            3.1
*/
		if(0x3400 <= code && code <= 0x4DB5) return (this.unicode_level >= 3.0) ? true : false;
		else if(0x4E00 <= code && code <= 0x9FA5) return (this.unicode_level >= 1.1) ? true : false;
		else if(0x9F46 <= code && code <= 0x9FBB) return (this.unicode_level >= 4.1) ? true : false;
		else if(0xF900 <= code && code <= 0xFA2D) return (this.unicode_level >= 1.1) ? true : false;
		else if(0xFA30 <= code && code <= 0xFA6A) return (this.unicode_level >= 3.2) ? true : false;
		else if(0xFA70 <= code && code <= 0xFAD9) return (this.unicode_level >= 4.1) ? true : false;
		else if(0x20000 <= code && code <= 0x2A6D6) return (this.unicode_level >= 3.1) ? true : false;
		else if(0x2F800 <= code && code <= 0x2FA1D) return (this.unicode_level >= 3.1) ? true : false;
		else return true; // assumed to be ok
	},
	isUnicodeStringVisible: function(codes)
	{
		var b = true;
		var i;
		
		for(i=0;i<codes.length;i++) {
			if(!this.isUnicodeVisible(codes[i])) {
				b = false;
				break;
			}
		}
		return b;
	}
});


